import { getToken } from '@/utils/cookies';
import { getWebsocketConfig } from '@/api/common';
// import { setAlarmStatus, setAlarmVoice } from '@/hooks/websocket';

class Websocket {
	websock: WebSocket | null;
	lockReconnect: boolean;
	timeout: number;
	timeoutObj: null | NodeJS.Timeout;
	serverTimeoutObj: null | NodeJS.Timeout;
	timeoutnum: null | NodeJS.Timeout;
	/** 接收到消息时执行的方法（创建了一直有） */
	callBackFn: (value) => void;
	/** 接收到数据时，触发的事件对象 */
	onMessageMethodObj: { [key: string]: (value) => void };
	/** 添加收到消息时的回调函数 */
	addCallBackFn(key, callBackFn: (value) => void) {
		this.onMessageMethodObj[key] = callBackFn;
	}
	/** 删除收到消息时的回调函数 */
	removeCallBackFn(key) {
		delete this.onMessageMethodObj[key];
	}

	constructor(successCallBack) {
		this.websock = null; // 建立的连接
		this.lockReconnect = false; // 是否真正建立连接
		this.timeout = 60 * 1e3; // 30秒一次心跳
		this.timeoutObj = null; // 外层心跳倒计时
		this.serverTimeoutObj = null; // 内层心跳检测
		this.timeoutnum = null; // 断开 重连倒计时
		this.onMessageMethodObj = {};

		this.callBackFn = successCallBack;
		this.initWebSocket();
	}

	async initWebSocket() {
		const { results } = await getWebsocketConfig();
		const token = getToken();
		// 初始化weosocket
		const wsuri = `ws://${results}/api/websocket/alarm/${token}`;
		this.websock = new WebSocket(wsuri);
		this.websock.onopen = this.websocketonopen;
		this.websock.onmessage = msg => {
			this.websocketonmessage(msg);
		};
		this.websock.onerror = this.websocketonerror;
		this.websock.onclose = this.websocketclose;
	}
	reconnect() {
		// 重新连接
		if (this.lockReconnect) {
			// 是否真正建立连接
			return;
		}
		this.lockReconnect = true;
		// 没连接上会一直重连，设置延迟避免请求过多
		this.timeoutnum && clearTimeout(this.timeoutnum);
		// 如果到了这里断开重连的倒计时还有值的话就清除掉
		this.timeoutnum = setTimeout(() => {
			// 然后新连接
			this.initWebSocket();
			this.lockReconnect = false;
		}, 60 * 1000);
	}
	start() {
		// 开启心跳
		this.timeoutObj && clearTimeout(this.timeoutObj);
		// 如果外层心跳倒计时存在的话，清除掉
		this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
		// 如果内层心跳检测倒计时存在的话，清除掉
		this.timeoutObj = setTimeout(() => {
			// 重新赋值重新发送 进行心跳检测
			// 这里发送一个心跳，后端收到后，返回一个心跳消息，
			if (this.websock!.readyState === 1) {
				// 如果连接正常
				this.websock!.send('{"test":"heartCheck"}');
			} else {
				// 否则重连
				this.reconnect();
			}
			this.serverTimeoutObj = setTimeout(() => {
				// 超时关闭重连
				this.websock!.close();
				this.reconnect();
			}, this.timeout);
		}, this.timeout);
	}
	websocketonopen(e) {
		// 连接成功
		console.log('成功');
	}
	websocketonerror() {
		setTimeout(() => {
			this.initWebSocket(); // 连接建立失败重连
		}, 60 * 1000);
	}
	websocketonmessage(e) {
		// 数据接受处理
		// 数据接收
		let redata = null;
		if (e.data) {
			redata = JSON.parse(e.data);
		}
		if (this.callBackFn) {
			console.log(redata);
			this.callBackFn(redata);
		}

		for (const key in this.onMessageMethodObj) {
			this.onMessageMethodObj[key](redata);
		}

		// 重置心跳 清除时间（清除内外两个心跳计时）
		clearTimeout(this.timeoutObj!);
		clearTimeout(this.serverTimeoutObj!);
		this.start();
	}
	websocketsend(Data) {
		// 数据发送
		this.websock && this.websock.send(Data);
	}
	websocketclose(e) {
		// 关闭
		console.log('断开连接', e);
	}
}

const websocketIns = new Websocket(resdata => {
	// setAlarmVoice(resdata);
	// setAlarmStatus(resdata);
});

export default websocketIns;
